package com.example.educational.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.XmlUtil;
import com.example.educational.controller.utils.Code;
import com.example.educational.controller.utils.SystemException;
import com.example.educational.entity.Corporate;
import com.example.educational.entity.VerCode.AesException;
import com.example.educational.entity.VerCode.WXBizMsgCrypt;
import com.example.educational.enums.OperationEnum;
import com.example.educational.service.AddressBookService;
import com.example.educational.service.CorporateService;
import com.example.educational.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;

import javax.xml.xpath.XPathConstants;
import java.util.Objects;

@Service
public class AddressServiceImpl implements AddressBookService {
    @Autowired
    Corporate corporate;

    @Autowired
    UserService userService;

    @Autowired
    CorporateService corporateService;

    @Override
    public String reqMsgURL(String sReqMsgSig, String sReqTimeStamp, String sReqNonce, String sReqData) throws AesException {
        // 1.验证数据完整性
        String sToken = corporate.getToken();
        String sEncodingAESKey = corporate.getEncodingAESKey();
        String sCorpID = corporate.getCorpId();
        String sMsg = null;
        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
            sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData);
        } catch (AesException e) {
            throw new RuntimeException(e.getMessage());
        }
        // 2.判断回调类型
        // 2.1解析xml文档
        Document document = XmlUtil.readXML(sMsg);
        // 2.2获取消息类型
        String changeType = null;
        Object msgType = XmlUtil.getByXPath("//MsgType", document, XPathConstants.STRING);
        if (ObjectUtil.equal(msgType, "event")) { // 事件类型
            Object event = XmlUtil.getByXPath("//Event", document, XPathConstants.STRING);
            if (ObjectUtil.equal(event, "change_contact")) { // 通讯录变更
                changeType = String.valueOf(XmlUtil.getByXPath("//ChangeType", document, XPathConstants.STRING));
            }
        }


        Boolean result = null;
        try {
            result = Boolean.FALSE;
            // 2.3判断事件操作
            if (ObjectUtil.isNotNull(changeType)) {

                // 2.3.1 获取用户Id
                String userId = String.valueOf(XmlUtil.getByXPath("//UserID", document, XPathConstants.STRING));

                switch (Objects.requireNonNull(OperationEnum.getType(changeType))) {
                    case CreateUser -> {
                        // 2.3.2 获取通讯录的AccessToken（因为2022年6月之后，接口升级，通讯录不再接收读取用户信息的回调）
                        String accessToken = corporateService.getToken4InnerApp(0);
                        result = userService.createUser(accessToken, userId);
                    }
                    case UpdateUser -> {
                        // 2.3.2 获取通讯录的AccessToken（因为2022年6月之后，接口升级，通讯录不再接收读取用户信息的回调）
                        String accessToken = corporateService.getToken4InnerApp(0);
                        String newUserId = String.valueOf(XmlUtil.getByXPath("//NewUserID", document, XPathConstants.STRING));
                        if (ObjectUtil.equals(newUserId, "")) {
                            result = userService.updateUser(accessToken, userId);
                        } else {
                            result = userService.updateUser(accessToken, userId, newUserId);
                        }
                    }
                    case DeleteUser -> {
                        result = userService.deleteUser(userId);

                    }
                    default -> throw new SystemException(Code.err, "回调事件类型异常，请管理员及时查看");

                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        return result ? "200" : "500";
    }

}
